using B.S.XZYData.Api.Wrter.Application.Command.Route;
using B.S.XZYData.Domain.LJC;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Linq;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Route
{
    /// <summary>
    /// 导入工艺路线处理器
    /// </summary>
    public class ImportRouteHandler : IRequestHandler<ImportRouteCommand, ApiResult<ImportRouteResult>>
    {
        private readonly IBaseRepository<RouteModel> _routeRepository;
        private readonly IBaseRepository<RouteStepModel> _routeStepRepository;
        private readonly ILogger<ImportRouteHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ImportRouteHandler(
            IBaseRepository<RouteModel> routeRepository,
            IBaseRepository<RouteStepModel> routeStepRepository,
            ILogger<ImportRouteHandler> logger)
        {
            _routeRepository = routeRepository;
            _routeStepRepository = routeStepRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理导入工艺路线命令
        /// </summary>
        public async Task<ApiResult<ImportRouteResult>> Handle(ImportRouteCommand request, CancellationToken cancellationToken)
        {
            var result = new ImportRouteResult();
            
            try
            {
                using var stream = new MemoryStream(request.FileBytes);
                
                // 根据文件扩展名决定使用哪种工作簿
                IWorkbook workbook;
                try
                {
                    // 尝试作为 XLSX 文件打开
                    workbook = new XSSFWorkbook(stream);
                }
                catch
                {
                    // 如果失败，重置流并尝试作为 XLS 文件打开
                    stream.Position = 0;
                    workbook = new HSSFWorkbook(stream);
                }

                // 导入工艺路线
                var routeWorksheet = GetWorksheetByName(workbook, "工艺路线");
                if (routeWorksheet != null)
                {
                    await ImportRoutes(routeWorksheet, result, request.OperateBy);
                }

                // 导入工艺路线工序
                var stepWorksheet = GetWorksheetByName(workbook, "工艺路线工序");
                if (stepWorksheet != null)
                {
                    await ImportRouteSteps(stepWorksheet, result, request.OperateBy);
                }

                _logger.LogInformation($"导入工艺路线完成，路线成功：{result.SuccessRouteCount}，路线失败：{result.FailedCount}，工序成功：{result.SuccessStepCount}，操作人：{request.OperateBy}");

                return new ApiResult<ImportRouteResult>
                {
                    Code = ApiEnum.Success,
                    Msg = $"导入完成，路线成功：{result.SuccessRouteCount}，失败：{result.FailedCount}，工序成功：{result.SuccessStepCount}",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"导入工艺路线失败，操作人：{request.OperateBy}");
                return new ApiResult<ImportRouteResult>
                {
                    Code = ApiEnum.Fail,
                    Msg = $"导入失败：{ex.Message}",
                    Data = result
                };
            }
        }

        /// <summary>
        /// 根据名称获取工作表
        /// </summary>
        private ISheet? GetWorksheetByName(IWorkbook workbook, string name)
        {
            for (int i = 0; i < workbook.NumberOfSheets; i++)
            {
                var sheet = workbook.GetSheetAt(i);
                if (sheet.SheetName == name)
                {
                    return sheet;
                }
            }
            return null;
        }

        /// <summary>
        /// 导入工艺路线
        /// </summary>
        private async Task ImportRoutes(ISheet worksheet, ImportRouteResult result, string operateBy)
        {
            if (worksheet.LastRowNum < 1) return;

            for (int rowIndex = 1; rowIndex <= worksheet.LastRowNum; rowIndex++)
            {
                var row = worksheet.GetRow(rowIndex);
                if (row == null) continue;

                try
                {
                    var routeCode = GetCellValue(row, 0);
                    var routeName = GetCellValue(row, 1);

                    if (string.IsNullOrWhiteSpace(routeCode) || string.IsNullOrWhiteSpace(routeName))
                    {
                        result.FailedCount++;
                        result.ErrorMessages.Add($"工艺路线第{rowIndex + 1}行：路线编号和路线名称不能为空");
                        continue;
                    }

                    // 检查是否已存在
                    var existingRoute = _routeRepository.GetAll()
                        .Where(x => x.Code == routeCode).ToList().FirstOrDefault();

                    if (existingRoute != null)
                    {
                        result.FailedCount++;
                        result.ErrorMessages.Add($"工艺路线第{rowIndex + 1}行：路线编号 {routeCode} 已存在");
                        continue;
                    }

                    var route = new RouteModel
                    {
                        Code = routeCode,
                        Name = routeName,
                        CreateTime = DateTime.Now,
                        CreateBy = operateBy
                    };

                    await _routeRepository.CreateAsync(route);
                    result.SuccessRouteCount++;
                }
                catch (Exception ex)
                {
                    result.FailedCount++;
                    result.ErrorMessages.Add($"工艺路线第{rowIndex + 1}行：处理数据时发生错误 - {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 导入工艺路线工序
        /// </summary>
        private async Task ImportRouteSteps(ISheet worksheet, ImportRouteResult result, string operateBy)
        {
            if (worksheet.LastRowNum < 1) return;

            for (int rowIndex = 1; rowIndex <= worksheet.LastRowNum; rowIndex++)
            {
                var row = worksheet.GetRow(rowIndex);
                if (row == null) continue;

                try
                {
                    var routeCode = GetCellValue(row, 0);
                    var processCode = GetCellValue(row, 3);
                    var processName = GetCellValue(row, 4);
                    var sequenceStr = GetCellValue(row, 2);

                    if (string.IsNullOrWhiteSpace(routeCode) || string.IsNullOrWhiteSpace(processCode))
                    {
                        result.FailedCount++;
                        result.ErrorMessages.Add($"工艺路线工序第{rowIndex + 1}行：路线编号和工序编号不能为空");
                        continue;
                    }

                    if (!int.TryParse(sequenceStr, out int sequence))
                    {
                        result.FailedCount++;
                        result.ErrorMessages.Add($"工艺路线工序第{rowIndex + 1}行：工序顺序格式不正确");
                        continue;
                    }

                    // 查找路线
                    var route = _routeRepository.GetAll()
                        .Where(x => x.Code == routeCode).ToList().FirstOrDefault();

                    if (route == null)
                    {
                        result.FailedCount++;
                        result.ErrorMessages.Add($"工艺路线工序第{rowIndex + 1}行：路线编号 {routeCode} 不存在");
                        continue;
                    }

                    var routeStep = new RouteStepModel
                    {
                        RouteId = route.Id,
                        ProcessCode = processCode,
                        ProcessName = processName,
                        Sequence = sequence,
                        CreateTime = DateTime.Now,
                        CreateBy = operateBy
                    };

                    await _routeStepRepository.CreateAsync(routeStep);
                    result.SuccessStepCount++;
                }
                catch (Exception ex)
                {
                    result.FailedCount++;
                    result.ErrorMessages.Add($"工艺路线工序第{rowIndex + 1}行：处理数据时发生错误 - {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 获取单元格值
        /// </summary>
        private string GetCellValue(IRow row, int columnIndex)
        {
            var cell = row.GetCell(columnIndex);
            if (cell == null) return string.Empty;

            return cell.CellType switch
            {
                CellType.String => cell.StringCellValue,
                CellType.Numeric => cell.NumericCellValue.ToString(),
                CellType.Boolean => cell.BooleanCellValue.ToString(),
                CellType.Formula => cell.CellFormula,
                _ => string.Empty
            };
        }
    }
} 